package com.example.testproj.aidl;

import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

import java.util.List;

/**
 * @des:
 * @author: 芮勤
 * @date: 2019-07-04 15:42
 * @see {@link }
 */
public abstract class MyAidlTestStub extends Binder implements MyAidlTestInterface {
    private static String DESCRIPTOR = "com.example.testproj.aidl.MyAidlTestInterface";

    public MyAidlTestStub() {
        this.attachInterface(this, DESCRIPTOR);
    }

    public static MyAidlTestInterface asInterface(IBinder iBinder) {
        if (iBinder == null) {
            return null;
        }
        String descriptor = null;
        try {
            descriptor = iBinder.getInterfaceDescriptor();
            IInterface iInterface = iBinder.queryLocalInterface(descriptor);
            if ((iInterface != null) && (iInterface instanceof MyAidlTestInterface)) {
                return (MyAidlTestInterface) iInterface;
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }


        return new MyAidlTestStub.Proxy(iBinder);
    }

    @Override
    public IBinder asBinder() {
        return this;
    }

    /**
     * 运行在服务端，由系统底层处理好以后，交给它处理
     * @param code
     * @param data
     * @param reply
     * @param flags
     * @return
     * @throws RemoteException
     */
    @Override
    protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
        Log.d("MyAidlTestInterface", "onTransact: 收到消息");
        switch (code) {
            case INTERFACE_TRANSACTION:
                reply.writeString(DESCRIPTOR);
                return true;
            case TRANSACTION_addbook:
                data.enforceInterface(DESCRIPTOR);
                Book arg0;
                if (data.readInt() != 0) {
                    arg0 = Book.CREATOR.createFromParcel(data);
                } else {
                    arg0 = null;
                }
                this.addBook(arg0);
                reply.writeNoException();
                return true;
            case TRANSACTION_getBookList:
                List<Book> bookList = this.getBookList();
                reply.writeNoException();
                reply.writeTypedList(bookList);
                return true;
        }
        return super.onTransact(code, data, reply, flags);
    }

    public static class Proxy implements MyAidlTestInterface {
        private IBinder remoter;

        public Proxy(IBinder remoter) {
            this.remoter = remoter;
        }

        public String getInterfaceDescriptor() {
            return DESCRIPTOR;
        }

        @Override
        public void addBook(Book book) throws RemoteException {
            Log.d("MyAidlTestInterface", "addBook: ");
            Parcel _data = Parcel.obtain();
            Parcel _replay = Parcel.obtain();

            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                if (book == null) {
                    _data.writeInt(0);
                } else {
                    _data.writeInt(1);
                    book.writeToParcel(_data, 0);
                }
                remoter.transact(TRANSACTION_addbook, _data, _replay, 0);
                _replay.readException();
            } finally {
                _data.recycle();
                _replay.recycle();
            }

        }

        @Override
        public List<Book> getBookList() throws RemoteException {
            Log.d("MyAidlTestInterface", "getBookList: ");
            Parcel _data = Parcel.obtain();
            Parcel _replay = Parcel.obtain();
            List<Book> bookList;
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                _data.writeInt(0);
                remoter.transact(TRANSACTION_getBookList, _data, _replay, 0);
                _replay.readException();
                bookList = _replay.createTypedArrayList(Book.CREATOR);
                return bookList;
            } finally {
                _data.recycle();
                _replay.recycle();
            }
        }

        @Override
        public IBinder asBinder() {
            return remoter;
        }
    }

    public static final int TRANSACTION_addbook = IBinder.FIRST_CALL_TRANSACTION + 0;
    public static final int TRANSACTION_getBookList = IBinder.FIRST_CALL_TRANSACTION + 1;
}
